package com.gln.bloger.dao.impl;

import java.util.HashMap;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;

import com.gln.bloger.dao.WebsiteDao;
import com.gln.bloger.exception.BlogerException;
import com.gln.bloger.exception.DBOperateException;
import com.gln.bloger.log.Logging;
import com.gln.bloger.pojos.User;
import com.gln.bloger.pojos.Website;
/**
 * web site manager
 * @author renxj
 *
 */
public class WebsiteDaoImpl extends BaseDaoImpl<Website> implements WebsiteDao {


	private HashMap<String, String> websiteHandleToId=  new HashMap<String, String>();
	
	/**
	 * get site by handle
	 */
	public Website getByHandle(String handle)
			throws BlogerException {
		/*this web site's "handle" and "id"  was cached in map*/
		if(websiteHandleToId.containsKey(handle)){
			
			Website website = this.get(websiteHandleToId.get(handle));
			if(null != website){
				Logging.debug("get website "+website.getName()+"by handle"+website.getHandle());
				return website;
			}else{
				/*cached data is old, remove it*/
				websiteHandleToId.remove(handle);
			}
		}
		/*cache failed*/
        try {
            Session session = getSession();
            Criteria criteria = session.createCriteria(Website.class);
            criteria.add(
                        Expression.conjunction()
                        .add(Expression.eq("handle", handle)));
            
            Website website = (Website) criteria.uniqueResult();
            // add mapping to cache
            if(website != null) {
                Logging.debug("websiteHandleToIdMap CACHE MISS - "+handle);
            	this.websiteHandleToId.put(website.getHandle(), website.getId());
            }
            return website;
        } catch (HibernateException e) {  
        	throw new DBOperateException(e.getMessage());
        }
	}

	/**
	 * get all sites 
	 */
	public List<Website> getWebsites() throws BlogerException {
		return getWebsites(Boolean.TRUE);
	}

	/**
	 * return all websites (enabled or disabled).
	 */
	@SuppressWarnings("unchecked")
	public List<Website> getWebsites(Boolean enabled)
			throws BlogerException {
		try {
			Session session = getSession();

			Criteria criteria = session.createCriteria(Website.class);
			/**
			 * add the expression
			 */
			criteria.add(Expression.conjunction().add(Expression.eq("enabled", enabled)));
			List<Website> websites = criteria.list();
			return websites;
		}catch(HibernateException e){
			throw new DBOperateException(e.getMessage());
		}
	}
	/**
	 * get by creator
	 * @param creator
	 * @return
	 * @throws BlogerException
	 */
	@SuppressWarnings("unchecked")
	public List<Website> getByCreator(User creator) throws BlogerException {
		try {
	         DetachedCriteria criteria = DetachedCriteria.forClass(Website.class);
	         criteria.add(Restrictions.eq("creator", creator));
	         List<Website> websites = getHibernateTemplate().
	                                           findByCriteria(criteria);
	         return websites;
	    } catch (HibernateException e) {
	    	throw new DBOperateException(e.getMessage());
	    }
	}
}
